package first.endtoend.webservices.mobile

import first.endtoend.Agent
import first.endtoend.Beneficiary
import first.endtoend.Family
import first.endtoend.JsonHelper
import first.endtoend.RationCard
import first.endtoend.Tag
import first.endtoend.Trace
import first.endtoend.TraceDetail
import first.endtoend.TraceView
import first.endtoend.*
import first.endtoend.messages.MessageCode
import grails.converters.JSON
import org.springframework.web.multipart.commons.CommonsMultipartFile
import sun.misc.BASE64Decoder

/**
 * @author Olfa
 * This webservice is responsible for transactions made by an agent
 */
class WebserviceController
{

    def retrieveAidService
    def familyService
    TraceView traceInstance
    Tag tag
    Trace trace
    Family family
    Agent agentInstance
    String login
    String password
    //commons variable
    def springSecurityService
    Family familyInstance
    def beforeInterceptor = [action: this.&init]

    /**
     *
     * @return not found message if tag associated to rationCard  doesn't exist in DB
     *            OR Malformed request if agent sent a bad request
     *            otherwise nothing
     */
    def init()
    {
        println(params?.Trace)
        def trace = params?.Trace


        if (!trace)
        {
            render([code: MessageCode.MALFORMED_REQUEST.value()] as JSON)
            return
        }
        traceInstance = JsonHelper.getObjectFromJson(trace, TraceView.class) as TraceView;
        familyInstance = Family.findById(traceInstance.beneficiary.family.id)
        RationCard rationCard = familyInstance.rationCard
        if (traceInstance != null)
        {
            tag = rationCard.tag
            if (!tag)
            {
                render([code: MessageCode.NOT_FOUND.value()] as JSON)
                return
            }

        } else
        {
            render([code: MessageCode.MALFORMED_REQUEST.value()] as JSON)
        }
    }

    /**
     *
     * @return this method get the trace sent by mobile app and add a trace of this transaction to database
     via retrieveAidService
     */

    def retrieveAid()
    {
        println "\n______________________\nRETRIEVE AID  " + params
        if (traceInstance != null)
        {
            def id = traceInstance.beneficiary.id

            def beneficiary
            //beneficiary is always sent here)

            beneficiary = Beneficiary.findById(id)
            agentInstance = Agent.findById(traceInstance.agentId)

            println " Agent " + agentInstance
            TraceDetail traceDetailInstance
            println("***Details :" + traceInstance.traceDetails)
            trace = new Trace(dateOp: traceInstance.dateOp,
                    longitude: traceInstance.longitude, latitude: traceInstance.latitude,
                    precision: traceInstance.precision, agent: agentInstance, beneficiary: beneficiary, tag: tag)

            List<TraceDetail> details = new ArrayList<TraceDetail>()


            if (traceInstance.pathPhoto)
            {
                byte[] btDataFile = new BASE64Decoder().decodeBuffer(traceInstance.pathPhoto);
                String photo = "web-app/transaction/" + System.currentTimeMillis() + ".png"
                File of = new File(photo)
                FileOutputStream osf = new FileOutputStream(of);
                osf.write(btDataFile);
                osf.flush();
                trace.pathPhoto = photo

            } else
            {
                println 'no photo'
            }

            if (retrieveAidService.successRetrieveAid(familyInstance, traceInstance.traceDetails))
            {
                trace.save(flush: true)
                if (trace.hasErrors())
                    trace.errors.each {
                        println it
                    }
                traceInstance.traceDetails.each {
                    println("************************" + it.quantityRecovered)
                    traceDetailInstance = new TraceDetail()
                    traceDetailInstance.product = it.product
                    traceDetailInstance.qteRecovered = it.quantityRecovered
                    traceDetailInstance.trace = trace
                    traceDetailInstance.save()
                    details.add(traceDetailInstance)

                }

                trace.details = details


                render([code: MessageCode.SUCCESS.value()] as JSON)
            } else
            {
                println("fail to retrieve")
                render([code: MessageCode.FAIL_RETRIEVE.value()] as JSON)
            }


        } else
        {
            //no trace received
        }

        return
    }

    /**
     *
     * @return this method implemented to add a beneficiary to a familyInstance
     */
    def addBeneficiary()
    {
        def benef = params?.beneficiary
        def familyInstance = Family.findById(params.family)
        if (familyInstance && params.firstName != null && params.firstName != "" && params.lastName != null && params.lastName != "")
        {
            def beneficiaryInstance = new Beneficiary(firstName: params.firstName, lastName: params.lastName, family: familyInstance).save(firstName: true)
            if (params.tataID)
            {
                beneficiaryInstance.tataId = params.tataId
            }
            if (params.photo)
            {
                CommonsMultipartFile photo = request.getFile('photo')
                photo.transferTo(new File(grailsApplication.config.productPhotos + photo.getName()))
                beneficiaryInstance.photoURL = photo.getName()
            }
            if (familyInstance.beneficiaries)
            {
                println("there is beneficiaries for this family")
                familyInstance.beneficiaries.add(beneficiaryInstance)
                familyInstance.save(flush: true)
                render([code: MessageCode.SUCCESS.value()] as JSON)
            } else
            {
                familyInstance.beneficiaries = new ArrayList<Beneficiary>()
                familyInstance.beneficiaries.add(beneficiaryInstance)
                familyInstance.save()
            }
        } else
        {
            render([code: MessageCode.FAIL_RETRIEVE.value()] as JSON)
        }
    }

}
